package eabnp.eflow.server.apicall;

import eabnp.basic.result.GResult;
import eabnp.basic.result.IResult;
import eabnp.basic.result.SGResult;
import eabnp.basic.util.ClassUtil;
import eabnp.basic.util.MiscUtil;
import eabnp.basic.util.StringUtil;
import eabnp.eflow.api.AppInterfaceType;
import eabnp.eflow.api.IAppInterface4EFlow;
import eabnp.eflow.api.IAppInterface4EFlow_D;
import eabnp.eflow.api.IAppInterface4EFlow_WS;
import eabnp.eflow.info.ctrlinfo.processctrl.actresult.ActResultListCtrl;
import eabnp.eflow.info.ctrlinfo.sysctrl.SysCtrlInfo;
import eabnp.eflow.info.ctrlinfo.sysctrl.basicinfo.OAServerInfo;
import eabnp.eflow.info.ctrlinfo.sysctrl.basicinfo.SysInfo;
import eabnp.eflow.misc.formula.FormulaArray;
import eabnp.eflow.server.impl.hb.cache.EFlowCache;
import eabnp.eflow.session.ESession;
import eabnp.eflow.tag.EFlowTagUtil;
import eabnp.etag.ETagUtil;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.codehaus.xfire.XFireFactory;
import org.codehaus.xfire.client.XFireProxyFactory;
import org.codehaus.xfire.service.Service;
import org.codehaus.xfire.service.binding.ObjectServiceFactory;

public class EFlowApiCall
{
  private static Map<String, IAppInterface4EFlow_WS> wsCallerMap = new ConcurrentHashMap();

  private static IResult getWSCaller(String wsUrl) {
    if (StringUtil.isNullOrEmptyStr(wsUrl)) {
      return SGResult.newFailureResult("空的Web服务URL");
    }

    IAppInterface4EFlow_WS caller = 
      (IAppInterface4EFlow_WS)wsCallerMap
      .get(wsUrl);
    if (caller != null) return GResult.newSuccessResult(caller);

    Service srvcModel = new ObjectServiceFactory()
      .create(IAppInterface4EFlow_WS.class);
    XFireProxyFactory factory = new XFireProxyFactory(
      XFireFactory.newInstance().getXFire());
    try
    {
      caller = (IAppInterface4EFlow_WS)factory.create(srvcModel, wsUrl);
    } catch (Exception ex) {
      ex.printStackTrace();
      return SGResult.newFailureResult(ex.getMessage()).addErrMsgToIResult(
        "创建WebService“" + wsUrl + "”的调用对象失败");
    }
    wsCallerMap.put(wsUrl, caller);

    return GResult.newSuccessResult(caller);
  }

  public static SGResult getEFlowApiInfo(String flowUN)
  {
    String sysUN = EFlowTagUtil.getSysUNFromName(flowUN);
    SysInfo sysInfo = EFlowCache.getSysInfo(ETagUtil.getCodeFromUN(sysUN));
    if (sysInfo == null) {
      return SGResult.newFailureResult("无法找到“" + sysUN + "”的系统")
        .addErrMsgPreStr("验证公式失败");
    }
    EFlowApiInfo info = new EFlowApiInfo();
    info.setType(sysInfo.getApiType());

    if (sysInfo.getApiType() == AppInterfaceType.LOCAL)
    {
      String className = sysInfo.getApiClassName();
      GResult gr = ClassUtil.getInstanceOfClass(className);
      if (gr.isFailure()) {
        return SGResult.newFailureResult("无法获得接口类“" + className + "”的实例")
          .addErrMsgPreStr("验证公式失败");
      }

      if (sysInfo.isUseDiiopCfg())
      {
        OAServerInfo oaServer = EFlowCache.getOAServerInfoByFlowUN(flowUN);
        if (oaServer == null) {
          return SGResult.newFailureResult("无法获取Domino OAServer的连接配置")
            .addErrMsgPreStr("验证公式失败");
        }
        if (!ClassUtil.isInterfaceImplents(gr.getResultObject().getClass(), 
          IAppInterface4EFlow_D.class.getName())) {
          return SGResult.newFailureResult(
            "指定的类“" + className + "”没有实现接口“" + 
            IAppInterface4EFlow_D.class.getName() + "”")
            .addErrMsgPreStr("验证公式失败");
        }
        IAppInterface4EFlow_D api = (IAppInterface4EFlow_D)gr.getResultObject();

        info.setUseDiiopCfg(true);
        info.setApiObj_D(api);
        info.setDiiopServer(oaServer.getDiiopServer());
        info.setDiiopPort(oaServer.getDiiopPort());
        info.setDiiopUser(oaServer.getDiiopUser());
        info.setDiiopPwd(oaServer.getDiiopPwd());

        return SGResult.newSuccessResult(info);
      }

      if (!ClassUtil.isInterfaceImplents(gr.getResultObject().getClass(), 
        IAppInterface4EFlow.class.getName())) {
        return SGResult.newFailureResult(
          "指定的类“" + className + "”没有实现接口“" + 
          IAppInterface4EFlow.class.getName() + "”").addErrMsgPreStr(
          "验证公式失败");
      }
      IAppInterface4EFlow api = (IAppInterface4EFlow)gr.getResultObject();
      info.setApiObj(api);

      return SGResult.newSuccessResult(info);
    }

    info.setWebserviceUser(sysInfo.getWebserviceUser());
    info.setWebservicePwd(sysInfo.getWebservicePwd());
    info.setWebserviceUrl(sysInfo.getWebserviceUrl());

    return SGResult.newSuccessResult(info);
  }

  public static SGResult getEFlowApiInfo(SysInfo sysInfo, String userUN, String flowUN, String processId)
  {
    String sysCode = sysInfo.getCode();
    sysInfo = EFlowCache.getSysInfo(sysCode);

    if (sysInfo == null) {
      return SGResult.newFailureResult("无法找到代码为“" + sysCode + "”的系统")
        .addErrMsgPreStr("验证公式失败");
    }
    EFlowApiInfo info = new EFlowApiInfo();
    info.setType(sysInfo.getApiType());

    if (sysInfo.getApiType() == AppInterfaceType.LOCAL)
    {
      String className = sysInfo.getApiClassName();
      GResult gr = ClassUtil.getInstanceOfClass(className);
      if (gr.isFailure()) {
        return SGResult.newFailureResult("无法获得接口类“" + className + "”的实例")
          .addErrMsgPreStr("验证公式失败");
      }

      if (sysInfo.isUseDiiopCfg())
      {
        OAServerInfo oaServer = EFlowCache.getOAServerInfoByFlowUN(flowUN);
        if (oaServer == null) {
          return SGResult.newFailureResult("无法获取Domino OAServer的连接配置")
            .addErrMsgPreStr("验证公式失败");
        }
        if (!ClassUtil.isInterfaceImplents(gr.getResultObject().getClass(), 
          IAppInterface4EFlow_D.class.getName())) {
          return SGResult.newFailureResult(
            "指定的类“" + className + "”没有实现接口“" + 
            IAppInterface4EFlow_D.class.getName() + "”")
            .addErrMsgPreStr("验证公式失败");
        }
        IAppInterface4EFlow_D api = (IAppInterface4EFlow_D)gr.getResultObject();

        info.setUseDiiopCfg(true);
        info.setApiObj_D(api);
        info.setDiiopServer(oaServer.getDiiopServer());
        info.setDiiopPort(oaServer.getDiiopPort());
        info.setDiiopUser(oaServer.getDiiopUser());
        info.setDiiopPwd(oaServer.getDiiopPwd());

        return SGResult.newSuccessResult(info);
      }

      if (!ClassUtil.isInterfaceImplents(gr.getResultObject().getClass(), 
        IAppInterface4EFlow.class.getName())) {
        return SGResult.newFailureResult(
          "指定的类“" + className + "”没有实现接口“" + 
          IAppInterface4EFlow.class.getName() + "”").addErrMsgPreStr(
          "验证公式失败");
      }
      IAppInterface4EFlow api = (IAppInterface4EFlow)gr.getResultObject();
      info.setApiObj(api);

      return SGResult.newSuccessResult(info);
    }

    info.setWebserviceUser(sysInfo.getWebserviceUser());
    info.setWebservicePwd(sysInfo.getWebservicePwd());
    info.setWebserviceUrl(sysInfo.getWebserviceUrl());

    return SGResult.newSuccessResult(info);
  }

  public static SGResult getEFlowApiInfo(ESession es, String userUN, String flowUN, String processId)
  {
    SysInfo sysInfo = es.getSysCtrlInfo().getSysInfo();
    return getEFlowApiInfo(sysInfo, userUN, flowUN, processId);
  }

  public static SGResult validateFormula(ESession es, String userUN, String flowUN, String processId, FormulaArray formulas, String appData)
  {
    SysInfo sysInfo = es.getSysCtrlInfo().getSysInfo();
    String sysCode = sysInfo.getCode();
    sysInfo = EFlowCache.getSysInfo(sysCode);

    if (sysInfo == null) {
      return SGResult.newFailureResult("无法找到代码为“" + sysCode + "”的系统")
        .addErrMsgPreStr("验证公式失败");
    }
    if (sysInfo.getApiType() == AppInterfaceType.LOCAL)
    {
      String className = sysInfo.getApiClassName();
      GResult gr = ClassUtil.getInstanceOfClass(className);
      if (gr.isFailure()) {
        return SGResult.newFailureResult("无法获得接口类“" + className + "”的实例")
          .addErrMsgPreStr("验证公式失败");
      }

      if (sysInfo.isUseDiiopCfg())
      {
        if (!ClassUtil.isInterfaceImplents(gr.getResultObject().getClass(), 
          IAppInterface4EFlow_D.class.getName())) {
          return SGResult.newFailureResult(
            "指定的类“" + className + "”没有实现接口“" + 
            IAppInterface4EFlow_D.class.getName() + "”")
            .addErrMsgPreStr("验证公式失败");
        }

        OAServerInfo oaServer = EFlowCache.getOAServerInfoByFlowUN(flowUN);
        if (oaServer == null) {
          return SGResult.newFailureResult("无法获取Domino OAServer的连接配置")
            .addErrMsgPreStr("验证公式失败");
        }
        IAppInterface4EFlow_D api = (IAppInterface4EFlow_D)gr.getResultObject();
        return api.validateFormula(oaServer.getDiiopServer(), 
          oaServer.getDiiopPort(), oaServer.getDiiopUser(), oaServer.getDiiopPwd(), 
          userUN, flowUN, processId, formulas, appData);
      }

      if (!ClassUtil.isInterfaceImplents(gr.getResultObject().getClass(), 
        IAppInterface4EFlow.class.getName())) {
        return SGResult.newFailureResult(
          "指定的类“" + className + "”没有实现接口“" + 
          IAppInterface4EFlow.class.getName() + "”").addErrMsgPreStr(
          "验证公式失败");
      }
      IAppInterface4EFlow api = (IAppInterface4EFlow)gr.getResultObject();

      return api.validateFormula(userUN, flowUN, processId, formulas, appData);
    }

    IResult r = getWSCaller(sysInfo.getWebserviceUrl());
    if (r.isFailure()) return r.toSGResult();
    IAppInterface4EFlow_WS caller = (IAppInterface4EFlow_WS)r.getResultObject();
    byte[] bytes = (byte[])null;
    SGResult sr = null;
    try {
      bytes = caller.validateFormula(sysInfo.getWebserviceUser(), 
        sysInfo.getWebservicePwd(), userUN, flowUN, processId, 
        MiscUtil.objSerializeToByteArray(formulas), appData);
      sr = (SGResult)MiscUtil.byteArrayAntiSerializeToObj(bytes);
    } catch (Exception ex) {
      return SGResult.newFailureResult(ex.getMessage()).addErrMsgPreStr(
        "WebService调用失败");
    }
    return sr;
  }

  public static SGResult getTodoItemInfo(EFlowApiInfo apiInfo, String userUN, String flowUN, String processId, ActResultListCtrl arlCtrl, String appData)
  {
    if (apiInfo.getType() == AppInterfaceType.LOCAL) {
      if (apiInfo.isUseDiiopCfg())
      {
        IAppInterface4EFlow_D api = apiInfo.getApiObj_D();
        return api.getTodoItemInfo(apiInfo.getDiiopServer(), 
          apiInfo.getDiiopPort(), apiInfo.getDiiopUser(), apiInfo.getDiiopPwd(), 
          userUN, flowUN, processId, appData);
      }

      IAppInterface4EFlow api = apiInfo.getApiObj();
      return api.getTodoItemInfo(userUN, flowUN, processId, appData);
    }

    IResult r = getWSCaller(apiInfo.getWebserviceUrl());
    if (r.isFailure()) return r.toSGResult();
    IAppInterface4EFlow_WS caller = (IAppInterface4EFlow_WS)r.getResultObject();
    byte[] bytes = (byte[])null;
    SGResult sr = null;
    try {
      bytes = caller.getTodoItemInfo(apiInfo.getWebserviceUser(), 
        apiInfo.getWebservicePwd(), userUN, flowUN, processId, appData);
      sr = (SGResult)MiscUtil.byteArrayAntiSerializeToObj(bytes);
    } catch (Exception ex) {
      return SGResult.newFailureResult(ex.getMessage()).addErrMsgPreStr(
        "WebService调用失败");
    }
    return sr;
  }

  public static SGResult operateActResult(EFlowApiInfo apiInfo, String userUN, String flowUN, String processId, ActResultListCtrl arlCtrl, String appData)
  {
    String sysCode = ETagUtil.getCodeFromUN(
      EFlowTagUtil.getSysUNFromName(flowUN));
    SysInfo sysInfo = EFlowCache.getSysInfo(sysCode);

    if (sysInfo == null) {
      return SGResult.newFailureResult("无法找到代码为“" + sysCode + "”的系统")
        .addErrMsgPreStr("验证公式失败");
    }
    if (sysInfo.getApiType() == AppInterfaceType.LOCAL)
    {
      String className = sysInfo.getApiClassName();
      GResult gr = ClassUtil.getInstanceOfClass(className);
      if (gr.isFailure()) {
        return SGResult.newFailureResult("无法获得接口类“" + className + "”的实例")
          .addErrMsgPreStr("处理操作结果失败");
      }

      if (sysInfo.isUseDiiopCfg())
      {
        if (!ClassUtil.isInterfaceImplents(gr.getResultObject().getClass(), 
          IAppInterface4EFlow_D.class.getName())) {
          return SGResult.newFailureResult(
            "指定的类“" + className + "”没有实现接口“" + 
            IAppInterface4EFlow_D.class.getName() + "”")
            .addErrMsgPreStr("处理操作结果失败");
        }
        IAppInterface4EFlow_D api = (IAppInterface4EFlow_D)gr.getResultObject();
        return api.operateActResult(apiInfo.getDiiopServer(), 
          apiInfo.getDiiopPort(), apiInfo.getDiiopUser(), apiInfo.getDiiopPwd(), 
          userUN, flowUN, processId, arlCtrl, appData);
      }

      if (!ClassUtil.isInterfaceImplents(gr.getResultObject().getClass(), 
        IAppInterface4EFlow.class.getName())) {
        return SGResult.newFailureResult(
          "指定的类“" + className + "”没有实现接口“" + 
          IAppInterface4EFlow.class.getName() + "”").addErrMsgPreStr(
          "验证公式失败");
      }
      IAppInterface4EFlow api = (IAppInterface4EFlow)gr.getResultObject();

      return api.operateActResult(userUN, flowUN, processId, arlCtrl, appData);
    }

    IResult r = getWSCaller(apiInfo.getWebserviceUrl());
    if (r.isFailure()) return r.toSGResult();
    IAppInterface4EFlow_WS caller = (IAppInterface4EFlow_WS)r.getResultObject();
    byte[] bytes = (byte[])null;
    SGResult sr = null;
    try {
      bytes = caller.operateActResult(apiInfo.getWebserviceUser(), 
        apiInfo.getWebservicePwd(), userUN, flowUN, processId, 
        MiscUtil.objSerializeToByteArray(arlCtrl), appData);
      sr = (SGResult)MiscUtil.byteArrayAntiSerializeToObj(bytes);
    } catch (Exception ex) {
      return SGResult.newFailureResult(ex.getMessage()).addErrMsgPreStr(
        "WebService调用失败");
    }
    return sr;
  }
}